/**
 * 
 */
package com.lanswon.qzsmk.service.preService.impl;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.apache.shiro.SecurityUtils;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.lanswon.qzsmk.base.AccountContants;
import com.lanswon.qzsmk.base.AppContants;
import com.lanswon.qzsmk.base.CardContants;
import com.lanswon.qzsmk.base.PreServcieContants;
import com.lanswon.qzsmk.dao.AppKindMapper;
import com.lanswon.qzsmk.dao.AppOpenRegMapper;
import com.lanswon.qzsmk.dao.BikeSectionMapper;
import com.lanswon.qzsmk.dao.BusinessMapper;
import com.lanswon.qzsmk.dao.CardControlMapper;
import com.lanswon.qzsmk.dao.CardDataMapper;
import com.lanswon.qzsmk.dao.CardTypeMapper;
import com.lanswon.qzsmk.dao.CertMapper;
import com.lanswon.qzsmk.dao.FeeRulesMapper;
import com.lanswon.qzsmk.dao.PersonalMapper;
import com.lanswon.qzsmk.dao.TransGlideMapper;
import com.lanswon.qzsmk.dao.TxnDtlMapper;
import com.lanswon.qzsmk.exception.ApplicationException;
import com.lanswon.qzsmk.exception.ErrorCode;
import com.lanswon.qzsmk.exception.SystemException;
import com.lanswon.qzsmk.model.ActiveUser;
import com.lanswon.qzsmk.model.AppOpenReg;
import com.lanswon.qzsmk.model.BikeSection;
import com.lanswon.qzsmk.model.Business;
import com.lanswon.qzsmk.model.CardControl;
import com.lanswon.qzsmk.model.CardData;
import com.lanswon.qzsmk.model.CardType;
import com.lanswon.qzsmk.model.Cert;
import com.lanswon.qzsmk.model.FeeRules;
import com.lanswon.qzsmk.model.Personal;
import com.lanswon.qzsmk.model.TransGlide;
import com.lanswon.qzsmk.model.TxnDtl;
import com.lanswon.qzsmk.service.preService.BikeService;
import com.lanswon.qzsmk.util.CommonUtil;
import com.lanswon.qzsmk.util.HttpUtil;
import com.lanswon.qzsmk.util.SequenceNumberUtil;
import com.lanswon.qzsmk.vo.BikeConsumeRecord;
import com.lanswon.qzsmk.vo.ResponseHead;
import com.lanswon.qzsmk.vo.ResultVo;
import com.lanswon.qzsmk.vo.VoucherVo;

/**
 * @author sun
 *
 */
@Service
@SuppressWarnings("unused")
public class BikeServiceImpl implements BikeService {

	@Autowired
	CardControlMapper cardControlMapper;

	@Autowired
	CardDataMapper cardDataMapper;

	@Autowired
	AppOpenRegMapper appOpenRegMapper;

	@Autowired
	PersonalMapper personalMapper;

	@Autowired
	BikeSectionMapper bikeSectionMapper;

	@Autowired
	AppKindMapper appKindMapper;

	@Autowired
	FeeRulesMapper feeRulesMapper;

	@Autowired
	TransGlideMapper transGlideMapper;

	@Autowired
	TxnDtlMapper txnDtlMapper;

	@Autowired
	CertMapper certMapper;

	@Autowired
	BusinessMapper businessMapper;

	@Autowired
	CardTypeMapper cardTypeMapper;

	@Override
	public JSONArray bikeAppRewriteCardData(String cardsn, String citizenCardNo) throws ApplicationException {
		CardControl query_CardControl = cardControlMapper.queryCardControlByCitizenCardNo(citizenCardNo);

		if (query_CardControl == null) {
			throw new ApplicationException(ErrorCode.QUERY_DATA_NULL, "当前卡片查询不到信息");
		}

		if (query_CardControl.getCardStatus().equals(CardContants.CARD_STATE_NORMAL)) {
			AppOpenReg query_AppOpenReg = appOpenRegMapper.queryAppOpenRegByCardNoAndFlag(citizenCardNo,
					AppContants.APP_FLAG_BIKE);
			if (query_AppOpenReg != null && AppContants.APP_STATUS_OPEN.equals(query_AppOpenReg.getAppStatus())) {

				JSONObject js = queryBikeUserByCitizenCardNo(citizenCardNo);
				ResponseHead g = JSON.parseObject(js.getString("head"), ResponseHead.class);
				if (code0001.equals(g.getRsltcode())) {
					throw new ApplicationException(ErrorCode.OTHER_EXCEPTION, "当前卡片未开通自行车应用");
				}
				js = js.getJSONObject("body");
				String vipno = js.getString("vipno");
				String vipcardsn = js.getString("vipcardsn");

				js = rewriteMemberCardData(cardsn, citizenCardNo, vipno, vipcardsn);
				g = JSON.parseObject(js.getString("head"), ResponseHead.class);
				if (!code0000.equals(g.getRsltcode())) {
					throw new ApplicationException(ErrorCode.OTHER_EXCEPTION, g.getRsltdesc());
				}

				return js.getJSONArray("sectioninfo");

			} else {
				throw new ApplicationException(ErrorCode.CARD_STATUS_EXCEPTION, "卡片没有开通自行车应用，无法重写卡");
			}

		} else {
			// 此卡异常，不得开通应用，请先查询卡状态
			throw new ApplicationException(ErrorCode.CARD_STATUS_EXCEPTION, "卡片状态异常，无法写卡");
		}

	}

	@Override
	public void bikeAppRechargeRevoke(String citizenCardNo) throws ApplicationException {
		Cert cert = certMapper.queryPreviousCertByCitizenCardNo(citizenCardNo);
		if (!cert.getCertType().equals(CardContants.BIKE_RECHARGE_VOUCHER)) {
			throw new ApplicationException(ErrorCode.OTHER_EXCEPTION, "充值后已办理其他业务，无法撤销");
		}
		// 查询自行车用户信息
		JSONObject js = queryBikeUserByCitizenCardNo(citizenCardNo);
		ResponseHead g = JSON.parseObject(js.getString("head"), ResponseHead.class);
		if (code0001.equals(g.getRsltcode())) {
			throw new ApplicationException(ErrorCode.OTHER_EXCEPTION, "当前卡片未开通自行车应用");
		}
		js = js.getJSONObject("body");
		String vipno = js.getString("vipno");
		String vipcardsn = js.getString("vipcardsn");
		js = rechargeReverse(vipno, vipcardsn, cert.getBusinessNo());
		g = JSON.parseObject(js.getString("head"), ResponseHead.class);

		if (!code0000.equals(g.getRsltcode())) {
			throw new ApplicationException(ErrorCode.OTHER_EXCEPTION, g.getRsltdesc());
		}
	}

	@Override
	public void bikeAppLossAndUnbind(String citizenCardNo, String status) throws ApplicationException {

		CardControl query_CardControl = cardControlMapper.queryCardControlByCitizenCardNo(citizenCardNo);

		if (query_CardControl == null) {
			throw new ApplicationException(ErrorCode.QUERY_DATA_NULL, "当前卡片查询不到信息");
		}

		// 查询自行车用户信息
		JSONObject js = queryBikeUserByCitizenCardNo(citizenCardNo);
		ResponseHead g = JSON.parseObject(js.getString("head"), ResponseHead.class);
		if (code0001.equals(g.getRsltcode())) {
			throw new ApplicationException(ErrorCode.OTHER_EXCEPTION, "当前卡片未开通自行车应用");
		}
		js = js.getJSONObject("body");
		String vipno = js.getString("vipno");

		if (status.equals(loss_status)) {
			// 挂失
			if (query_CardControl.getCardStatus().equals(CardContants.CARD_STATE_NORMAL)) {
				AppOpenReg query_AppOpenReg = appOpenRegMapper.queryAppOpenRegByCardNoAndFlag(citizenCardNo,
						AppContants.APP_FLAG_BIKE);
				if (query_AppOpenReg != null && AppContants.APP_STATUS_OPEN.equals(query_AppOpenReg.getAppStatus())) {
					cardReportLossOrRelease(vipno, status);
				} else {
					throw new ApplicationException(ErrorCode.CARD_STATUS_EXCEPTION, "卡片没有开通自行车应用，无法挂失");
				}

			} else {
				// 此卡异常，不得开通应用，请先查询卡状态
				throw new ApplicationException(ErrorCode.CARD_STATUS_EXCEPTION, "卡片状态异常，无法挂失");
			}

		} else if (status.equals(unbind_status)) {
			// 解挂
			if (query_CardControl.getCardStatus().equals(CardContants.CARD_STATE_OFFICIAL_LOSS)
					|| query_CardControl.getCardStatus().equals(CardContants.CARD_STATE_ORAL_LOSS)) {
				AppOpenReg query_AppOpenReg = appOpenRegMapper.queryAppOpenRegByCardNoAndFlag(citizenCardNo,
						AppContants.APP_FLAG_BIKE);

				if (query_AppOpenReg == null) {
					throw new ApplicationException(ErrorCode.QUERY_DATA_NULL, "卡片没有开通自行车应用，无法解挂");
				}

				if (AppContants.APP_STATUS_OPEN.equals(query_AppOpenReg.getAppStatus())) {
					throw new ApplicationException(ErrorCode.CARD_STATUS_EXCEPTION, "卡片状态正常，无需解挂");
				}
				js = cardReportLossOrRelease(vipno, status);
				g = JSON.parseObject(js.getString("head"), ResponseHead.class);
				if (!code0000.equals(g.getRsltcode())) {
					throw new ApplicationException(ErrorCode.OTHER_EXCEPTION, g.getRsltdesc());
				}

			} else {
				// 此卡异常，不得开通应用，请先查询卡状态
				throw new ApplicationException(ErrorCode.CARD_STATUS_EXCEPTION, "该卡不是挂失状态，无法解挂");
			}

		}

	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Map<String, Object> openBikeApp(String citizenCardNo, String cardsn) throws ApplicationException {
		Map<String, Object> map = new HashMap<>();
		if (StringUtils.isEmpty(citizenCardNo)) {
			throw new ApplicationException(ErrorCode.OBJECT_IS_NULL, "市民卡号为空");
		}
		CardControl query_CardControl = cardControlMapper.queryCardControlByCitizenCardNo(citizenCardNo);

		if (query_CardControl == null) {
			throw new ApplicationException(ErrorCode.QUERY_DATA_NULL, "当前卡片查询不到信息");
		}
		if (query_CardControl.getCardStatus().equals(CardContants.CARD_STATE_NORMAL)) {
			AppOpenReg query_AppOpenReg = appOpenRegMapper.checkIsOpen(citizenCardNo, AppContants.APP_FLAG_BIKE);
			// 20181206 hgl 修改以下一行
			if (query_AppOpenReg != null && "1".equals(query_AppOpenReg.getAppStatus())) {
				throw new ApplicationException(ErrorCode.DATA_EXIST, "当前卡片已开通自行车引用");
			}

			Personal query_Personal = personalMapper.queryPersonalBycitizenCardNo(citizenCardNo);
			if (query_Personal == null) {
				throw new ApplicationException(ErrorCode.QUERY_DATA_NULL, "当前卡片无个人信息");
			}

			// 查询是否已办理自行车卡

			JSONObject js = queryBikeUserByIdNo(query_Personal.getPaperType(), query_Personal.getPaperNo());
			ResponseHead g = JSON.parseObject(js.getString("head"), ResponseHead.class);

			if (code0003.equals(g.getRsltcode())) {
				throw new ApplicationException(ErrorCode.DATA_EXIST, "当前客户已办理自行车卡");
			}
			// 请求扇区
			map.put("key", queryBikeSection(citizenCardNo, cardsn));

			// 写数据
			js = writeData(cardsn, cardtype, citizenCardNo, query_Personal.getPaperType(), query_Personal.getPaperNo(),
					DateFormatUtils.format(query_Personal.getBirthday(), "yyyyMMdd"));
			g = JSON.parseObject(js.getString("head"), ResponseHead.class);

			js = js.getJSONObject("body");
			map.put("data", js.getJSONArray("sectioninfo"));
			map.put("vipno", js.getString("vipno"));
			map.put("vipcardsn", js.getString("vipcardsn"));

		} else {
			// 此卡异常，不得开通应用，请先查询卡状态
			throw new ApplicationException(ErrorCode.CARD_STATUS_EXCEPTION, "卡片状态异常，无法开通应用");
		}

		return map;
	}

	@Override
	public Map<String, Object> SupplementAndChangeCard(String oldCitizenCardNo, String newCitizenCardNo,
			String newCardsn) throws ApplicationException {

		Map<String, Object> map = new HashMap<>();

		// 查询自行车用户信息

		JSONObject js = queryBikeUserByCitizenCardNo(oldCitizenCardNo);
		ResponseHead g = JSON.parseObject(js.getString("head"), ResponseHead.class);
		if (code0001.equals(g.getRsltcode())) {
			throw new ApplicationException(ErrorCode.OTHER_EXCEPTION, "当前卡片未开通自行车应用");
		}
		js = js.getJSONObject("body");
		String oldvipno = js.getString("vipno");
		String oldvipcardsn = js.getString("vipcardsn");
		// 请求最后一次借还状态
		js = memberBorrowOrBackLastTime(oldvipno, oldvipcardsn);

		js = js.getJSONObject("body");
		String allowStatus = js.getString("allow");// 借还状态
		if (allowStatus_no.equals(allowStatus)) {
			throw new ApplicationException(ErrorCode.OTHER_EXCEPTION, "当前卡片会员状态：挂失或者注销，禁止借车");
		}

		// 请求扇区
		map.put("key", queryBikeSection(newCitizenCardNo, newCardsn));

		// 写数据

		js = memberExchangeNewCard(oldvipno, newCardsn, newCitizenCardNo);
		g = JSON.parseObject(js.getString("head"), ResponseHead.class);

		js = js.getJSONObject("body");
		String newvipno = js.getString("newvipno");
		String newvipcardsn = js.getString("newvipcardsn");
		js = js.getJSONObject("writedata");
		map.put("data", js.getJSONArray("sectioninfo"));

		map.put("oldvipno", oldvipno);
		map.put("oldvipcardsn", oldvipcardsn);
		map.put("newvipno", newvipno);
		map.put("newvipcardsn", newvipcardsn);
		return map;
	}

	@Override
	public List<BikeSection> queryBikeSection(String citizenCardNo, String cardsn) throws ApplicationException {
		List<NameValuePair> parameForToken = new ArrayList<NameValuePair>();
		parameForToken.add(new BasicNameValuePair("cardsn", cardsn));

		JSONObject js = HttpUtil.doPost(PreServcieContants.bikeServiceIp + PreServcieContants.querySectionSecretKey,
				parameForToken);
		ResponseHead g = JSON.parseObject(js.getString("head"), ResponseHead.class);
		if (!code0000.equals(g.getRsltcode())) {
			throw new ApplicationException(ErrorCode.OTHER_EXCEPTION, g.getRsltdesc());
		}
		List<BikeSection> list = JSONArray.parseArray(js.getJSONObject("body").getJSONArray("sectioninfo")
				.toJSONString(), BikeSection.class);

		for (BikeSection b : list) {
			b.setCitizenCardNo(citizenCardNo);
		}
		List<BikeSection> query_list = bikeSectionMapper.queryBikeSection(citizenCardNo);
		if (query_list.size() == 0) {
			bikeSectionMapper.batchInsert(list);
		} else if (list.size() == query_list.size()) {
			boolean b = false;
			for (int i = 0; i < list.size(); i++) {
				if (!list.get(i).equals(query_list.get(i))) {
					b = true;
					break;
				}
			}
			if (b)
				bikeSectionMapper.batchUpdate(list);
		}

		return list;

	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public VoucherVo writeCardSuccess(String citizenCardNo, String cardsn, String recharge, String vipno,
			String vipcardsn) throws ApplicationException {
		ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getSession().getAttribute("activeUser");
		Personal query_Personal = personalMapper.queryPersonalBycitizenCardNo(citizenCardNo);
		CardControl query_CardControl = cardControlMapper.queryCardControlByCitizenCardNo(citizenCardNo);
		AppOpenReg query_AppOpenReg = appOpenRegMapper.checkIsOpen(citizenCardNo, AppContants.APP_FLAG_BIKE);
		CardData cardData = cardDataMapper.queryCardDataByCitizenCardNo(citizenCardNo);
		BigDecimal money = new BigDecimal(recharge);

		FeeRules feeRules = feeRulesMapper.queryFeeByAppTypeAndCardPCode(query_AppOpenReg.getAppType(),
				cardData.getCardpCode(), AccountContants.FEE_TYPE_DEPOSIT);

		// 注册会员
		// 20181205 hgl 修改以下一行
		JSONObject js = regMemberInfo(cardsn, citizenCardNo, vipno, vipcardsn, query_Personal.getCustomerName(),
				query_Personal.getGender(), query_Personal.getPaperType(), query_Personal.getPaperNo(),
				new SimpleDateFormat("yyyyMMdd").format(query_Personal.getBirthday()), recharge, feeRules.getFeeBln(),
				query_Personal.getContact() == null ? "" : query_Personal.getContact(),
				query_Personal.getMobile() == null ? "" : query_Personal.getMobile(), query_Personal.getCustomerName(),
				query_Personal.getMobile() == null ? "" : query_Personal.getMobile());

		Date now = new Date();

		Cert c_deposit = new Cert();
		c_deposit.setCertNo(SequenceNumberUtil.generatorCertNo());
		c_deposit.setCardControlId(query_CardControl.getCardControlId());
		c_deposit.setCertType(CardContants.BIKE_MIX_VOUCHER);
		c_deposit.setCardpCode(cardData.getCardpCode());
		c_deposit.setCardTypecode(cardData.getCardTypecode());
		c_deposit.setName(query_Personal.getCustomerName());
		c_deposit.setPaperType(query_Personal.getPaperType());
		c_deposit.setPaperNo(query_Personal.getPaperNo());
		// c.setStatus(status);
		c_deposit.setData("押金+充值本金凭证");
		c_deposit.setBranchNo(activeUser.getBranchNo());
		c_deposit.setCrtOperator(activeUser.getUserNo().toString());
		c_deposit.setCrtDate(now);
		c_deposit.setLastOperator(activeUser.getUserNo().toString());
		c_deposit.setLastDate(now);
		c_deposit.setBranch(activeUser.getBranchName());

		Business b_deposit = new Business();
		b_deposit.setBusinessNo(SequenceNumberUtil.generatorBusinessNo());
		b_deposit.setCardControlId(query_CardControl.getCardControlId());
		b_deposit.setCustomerNo(query_Personal.getCustomerNo());
		b_deposit.setCardpCode(cardData.getCardpCode());
		b_deposit.setTellerNo(activeUser.getUserNo().toString());
		b_deposit.setTransDate(now);
		b_deposit.setSeqStatus(CardContants.LSZT_NORMAL);
		b_deposit.setCertNo(c_deposit.getCertNo());

		// 自行车押金记录
		// 当日交易明细
		TxnDtl td_deposit = new TxnDtl();
		td_deposit.setCitizenCardNo(citizenCardNo);
		td_deposit.setIssCityCd(CardContants.CITY_CODE);
		td_deposit.setTxnCityCd(CardContants.CITY_CODE);
		td_deposit.setAppFlag(AppContants.APP_FLAG_BIKE);
		td_deposit.setCrdPhysTp(cardData.getCardPhysicalType());// 卡物理类型
		td_deposit.setCashFlag(AccountContants.CASH_FLAG_COLLECT); // 现金收付标志
																	// 0.无,1.收取
																	// 2.支出,3.收支
		// td_deposit. setTxnTp(bv.getCrdTxnType());// 卡交易类型 02 06
		td_deposit.setTxnDt(DateFormatUtils.format(now, "yyyyMMddHHmmss"));
		td_deposit.setTxnBalBef(new BigDecimal(0));// 账户交易前余额
		BigDecimal total = feeRules.getFeeBln().add(money);
		td_deposit.setTxnBalAft(total);
		td_deposit.setTxnAmt(total);
		td_deposit.setFeeTp(AccountContants.FEE_TYPE_BIKE_MIX);// 费用类型 0.本金
																// 1:工本费 2.交易手续费
																// 3:租金4:押金
		td_deposit.setAcceptTp(AccountContants.ACCEPTANCE_TYPE_NET);
		td_deposit.setAcceptCusNo(activeUser.getBranchNo());// 受理商户/网点编号
		td_deposit.setTxnTstFlg(AccountContants.TRANSACTION_TEST_FLAG_COMMON);// 交易测试标志
																				// "0"-普通;
																				// "1"-测试
		td_deposit.setTxnAdjFlg(AccountContants.TRANSACTION_FLOW_FLAG_NORMAL);// 交易流水标志
																				// "00"
																				// 正常
																				// "41"
																				// 撤销
		td_deposit.setWarrantid(c_deposit.getCertNo());// 凭证号
		td_deposit.setOprNo(activeUser.getUserNo().toString());// 操作员编号/终端操作员编号
		td_deposit.setTxnAttr(AccountContants.TXNTP_RECHARGE);// 交易性质
		td_deposit.setCrdCityCd(CardContants.CITY_CODE);// 卡城市代码
		td_deposit.setCardType(cardData.getCardTypecode());
		td_deposit.setRsvdFlags(AccountContants.TXNTP_RECHARGE); // 预留标志组
		td_deposit.setTxnType(AccountContants.TRADE_TYPE_BIKE);// 终端交易类型
		td_deposit.setTxnDate(DateFormatUtils.format(now, "yyyyMMdd")); // 交易日期
		td_deposit.setBusinessNo(td_deposit.getBusinessNo());//
		td_deposit.setPaymentType(AccountContants.PAYMENT_TYPE_CASH);// 支付方式 0
																		// 现金 1
																		// 兑换券
																		// 默认为0
		td_deposit.setPaymentTypeExt(AccountContants.STATUS_INVALID);// 支付方式是否扩展
																		// 0 否1
																		// 是
																		// 默认为0
		td_deposit.setRealTxnAmt(money);

		// 交易明细流水表
		TransGlide tg_deposit = new TransGlide();
		tg_deposit.setAcceptTp(AccountContants.ACCEPTANCE_TYPE_NET);// 受理类型
		tg_deposit.setAppFlag(AppContants.APP_FLAG_BIKE);// 应用标识
		tg_deposit.setAppType(query_AppOpenReg.getAppType());// 应用类型
		tg_deposit.setBranchNo(activeUser.getBranchNo());
		tg_deposit.setCitizenCardNo(citizenCardNo);// 市民卡号
		tg_deposit.setCashFlag(AccountContants.CASH_FLAG_COLLECT);// 现金收付标志
		tg_deposit.setFeeRuleId(feeRules.getFeeRuleId());// 卡费用规则ID
		tg_deposit.setFeeRulesId(feeRules.getFeeRulesId());// 卡费用细则ID
		tg_deposit.setFeeTp(AccountContants.FEE_TYPE_BIKE_MIX);// 费用类型
		tg_deposit.setOprNo(activeUser.getUserNo().toString());
		tg_deposit.setPaymentType(AccountContants.PAYMENT_TYPE_CASH);// 现金
		tg_deposit.setPaymentTypeExt(AccountContants.STATUS_INVALID);
		tg_deposit.setRptFlag(AccountContants.RPT_FLAG_NO);// 轧帐标识 0未过账
		tg_deposit.setTxnAdjFlg(AccountContants.TRANSACTION_FLOW_FLAG_NORMAL);// 交易流水标识
		tg_deposit.setTxnAmt(total);// 交易金额
		tg_deposit.setTxnDt(now);// 交易时间
		tg_deposit.setTxnTp(AccountContants.TXNTP_RECHARGE);// txnTp 交易类型
		tg_deposit.setBusinessNo(td_deposit.getBusinessNo());
		certMapper.insert(c_deposit);
		businessMapper.insert(b_deposit);
		txnDtlMapper.insert(td_deposit);
		transGlideMapper.insert(tg_deposit);

		CardType cardType = cardTypeMapper.queryCardTypeByCode(cardData.getCardTypecode());

		VoucherVo vo = new VoucherVo();
		vo.setCertNo(c_deposit.getCertNo());
		vo.setBusinessTypeName("开通自行车应用,押金和首充业务");
		vo.setCardType(cardType.getCardTypeName());
		vo.setOperator(activeUser.getUserNo().toString());
		vo.setNet(activeUser.getBranchNo());
		// 20181206 hgl 修改以下三行
		//充值与押金分开，充值计入交易
		vo.setTransactionAmount(recharge);
		vo.setFeeBln(feeRules.getFeeBln().toString());
		vo.setCurrentAmount(CommonUtil.convertMoney_00(money));
		vo.setTransactionDate(DateFormatUtils.format(now, "yyyy-MM-dd HH:mm:ss"));
		vo.setDate(DateFormatUtils.format(now, "yyyy-MM-dd"));
		return vo;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public VoucherVo closeBikeApp(String citizenCardNo) throws ApplicationException {
		ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getSession().getAttribute("activeUser");

		ResultVo resultVo = new ResultVo();
		CardControl query_CardControl = cardControlMapper.queryCardControlByCitizenCardNo(citizenCardNo);
		if (query_CardControl == null) {
			throw new ApplicationException(ErrorCode.QUERY_DATA_NULL, "当前卡片查询不到信息");
		}

		if (query_CardControl.getCardStatus().equals(CardContants.CARD_STATE_NORMAL)) {
			AppOpenReg query_AppOpenReg = appOpenRegMapper.checkIsOpen(citizenCardNo, AppContants.APP_FLAG_BIKE);
			if (query_AppOpenReg == null) {
				throw new ApplicationException(ErrorCode.QUERY_DATA_NULL, "当前卡片没有开通自行车应用");
			}

			Personal query_Personal = personalMapper.queryPersonalBycitizenCardNo(citizenCardNo);
			if (query_Personal == null) {
				throw new ApplicationException(ErrorCode.QUERY_DATA_NULL, "当前卡片无个人信息");
			}

			// 请求查询用户信息

			JSONObject js = queryBikeUserByCitizenCardNo(citizenCardNo);
			ResponseHead g = JSON.parseObject(js.getString("head"), ResponseHead.class);

			if (code0001.equals(g.getRsltcode())) {
				throw new ApplicationException(ErrorCode.OTHER_EXCEPTION, "当前卡片未开通自行车应用");
			}
			js = js.getJSONObject("body");
			String balance = js.getString("balance");
			int b = Integer.valueOf(balance).intValue();
			BigDecimal money = new BigDecimal(b);
			if (b < 0) {
				throw new ApplicationException(ErrorCode.OTHER_EXCEPTION, "当前余额小于零，禁止退卡");
			}

			// js= js.getJSONObject("body");
			String vipno = js.getString("vipno");
			String vipcardsn = js.getString("vipcardsn");

			// 请求最后一次借还状态
			js = memberBorrowOrBackLastTime(vipno, String.valueOf(vipcardsn));

			js = js.getJSONObject("body");
			String allowStatus = js.getString("allow");// 借还状态
			if (allowStatus_no.equals(allowStatus)) {
				throw new ApplicationException(ErrorCode.OTHER_EXCEPTION, "当前卡片会员状态：挂失或者注销，禁止借车");
			}

			Date now = new Date();
			CardData cardData = cardDataMapper.queryCardDataByCitizenCardNo(citizenCardNo);

			FeeRules feeRules = feeRulesMapper.queryFeeByAppTypeAndCardPCode(query_AppOpenReg.getAppType(),
					cardData.getCardpCode(), AccountContants.FEE_TYPE_DEPOSIT);

			BigDecimal total = feeRules.getFeeBln().add(money);
			System.out.println("total==>" + total);
			Cert c_deposit = new Cert();
			c_deposit.setCertNo(SequenceNumberUtil.generatorCertNo());
			c_deposit.setCardControlId(query_CardControl.getCardControlId());
			c_deposit.setCertType(CardContants.REFUND_REGISTRATION_MIX);
			c_deposit.setCardpCode(cardData.getCardpCode());
			c_deposit.setCardTypecode(cardData.getCardTypecode());
			c_deposit.setName(query_Personal.getCustomerName());
			c_deposit.setPaperType(query_Personal.getPaperType());
			c_deposit.setPaperNo(query_Personal.getPaperNo());
			// c.setStatus(status);
			c_deposit.setData("自行车退（押金+余额）凭证");
			c_deposit.setBranchNo(activeUser.getBranchNo());
			c_deposit.setCrtOperator(activeUser.getUserNo().toString());
			c_deposit.setCrtDate(now);
			c_deposit.setLastOperator(activeUser.getUserNo().toString());
			c_deposit.setLastDate(now);
			c_deposit.setBranch(activeUser.getBranchName());

			Business b_deposit = new Business();
			b_deposit.setBusinessNo(SequenceNumberUtil.generatorBusinessNo());
			b_deposit.setCardControlId(query_CardControl.getCardControlId());
			b_deposit.setCustomerNo(query_Personal.getCustomerNo());
			b_deposit.setCardpCode(cardData.getCardpCode());
			b_deposit.setTellerNo(activeUser.getUserNo().toString());
			b_deposit.setTransDate(now);
			b_deposit.setSeqStatus(CardContants.LSZT_NORMAL);
			b_deposit.setCertNo(c_deposit.getCertNo());

			// 自行车押金+充值记录
			// 当日交易明细
			TxnDtl td_deposit = new TxnDtl();
			td_deposit.setCitizenCardNo(citizenCardNo);
			td_deposit.setIssCityCd(CardContants.CITY_CODE);
			td_deposit.setTxnCityCd(CardContants.CITY_CODE);
			td_deposit.setAppFlag(AppContants.APP_FLAG_BIKE);
			td_deposit.setCrdPhysTp(cardData.getCardPhysicalType());// 卡物理类型
			td_deposit.setCashFlag(AccountContants.CASH_FLAG_PAY); // 现金收付标志
																	// 0.无,1.收取
																	// 2.支出,3.收支
			// td_deposit. setTxnTp(bv.getCrdTxnType());// 卡交易类型 02 06
			td_deposit.setTxnDt(DateFormatUtils.format(now, "yyyyMMddHHmmss"));
			td_deposit.setTxnBalBef(money);// 账户交易前余额
			td_deposit.setTxnBalAft(new BigDecimal(0));
			td_deposit.setTxnAmt(total);
			td_deposit.setFeeTp(AccountContants.FEE_TYPE_BIKE_MIX);// 费用类型 0.本金
																	// 1:工本费
																	// 2.交易手续费
																	// 3:租金4:押金
			td_deposit.setAcceptTp(AccountContants.ACCEPTANCE_TYPE_NET);
			td_deposit.setAcceptCusNo(activeUser.getBranchNo());// 受理商户/网点编号
			td_deposit.setTxnTstFlg(AccountContants.TRANSACTION_TEST_FLAG_COMMON);// 交易测试标志
																					// "0"-普通;
																					// "1"-测试
			td_deposit.setTxnAdjFlg(AccountContants.TRANSACTION_FLOW_FLAG_NORMAL);// 交易流水标志
																					// "00"
																					// 正常
																					// "41"
																					// 撤销
			td_deposit.setWarrantid(c_deposit.getCertNo());// 凭证号
			td_deposit.setOprNo(activeUser.getUserNo().toString());// 操作员编号/终端操作员编号
			td_deposit.setTxnAttr(AccountContants.TXNTP_REFUND);// 交易性质
			td_deposit.setCrdCityCd(CardContants.CITY_CODE);// 卡城市代码
			td_deposit.setCardType(cardData.getCardTypecode());
			td_deposit.setRsvdFlags(AccountContants.TXNTP_REFUND); // 预留标志组
			td_deposit.setTxnType(AccountContants.TRADE_TYPE_BIKE);// 终端交易类型
			td_deposit.setTxnDate(DateFormatUtils.format(now, "yyyyMMdd")); // 交易日期
			td_deposit.setBusinessNo(td_deposit.getBusinessNo());//
			td_deposit.setPaymentType(AccountContants.PAYMENT_TYPE_CASH);// 支付方式
																			// 0
																			// 现金
																			// 1
																			// 兑换券
																			// 默认为0
			td_deposit.setPaymentTypeExt(AccountContants.STATUS_INVALID);// 支付方式是否扩展
																			// 0
																			// 否1
																			// 是
																			// 默认为0
			td_deposit.setRealTxnAmt(feeRules.getFeeBln());

			// 交易明细流水表
			TransGlide tg_deposit = new TransGlide();
			tg_deposit.setAcceptTp(AccountContants.ACCEPTANCE_TYPE_NET);// 受理类型
			tg_deposit.setAppFlag(AppContants.APP_FLAG_BIKE);// 应用标识
			tg_deposit.setAppType(query_AppOpenReg.getAppType());// 应用类型
			tg_deposit.setBranchNo(activeUser.getBranchNo());
			tg_deposit.setCitizenCardNo(citizenCardNo);// 市民卡号
			tg_deposit.setCashFlag(AccountContants.CASH_FLAG_PAY);// 现金收付标志
			tg_deposit.setFeeRuleId(feeRules.getFeeRuleId());// 卡费用规则ID
			tg_deposit.setFeeRulesId(feeRules.getFeeRulesId());// 卡费用细则ID
			tg_deposit.setFeeTp(AccountContants.FEE_TYPE_BIKE_MIX);// 费用类型
			tg_deposit.setOprNo(activeUser.getUserNo().toString());
			tg_deposit.setPaymentType(AccountContants.PAYMENT_TYPE_CASH);// 现金
			tg_deposit.setPaymentTypeExt(AccountContants.STATUS_INVALID);
			tg_deposit.setRptFlag(AccountContants.RPT_FLAG_NO);// 轧帐标识 0未过账
			tg_deposit.setTxnAdjFlg(AccountContants.TRANSACTION_FLOW_FLAG_NORMAL);// 交易流水标识
			tg_deposit.setTxnAmt(total);// 交易金额
			tg_deposit.setTxnDt(now);// 交易时间
			tg_deposit.setTxnTp(AccountContants.TXNTP_REFUND);// txnTp 交易类型
			tg_deposit.setBusinessNo(tg_deposit.getBusinessNo());
			certMapper.insert(c_deposit);
			businessMapper.insert(b_deposit);
			txnDtlMapper.insert(td_deposit);
			transGlideMapper.insert(tg_deposit);
			// 退卡返回 押金

			CardType cardType = cardTypeMapper.queryCardTypeByCode(cardData.getCardTypecode());
			// 退卡
			backCard(vipno);
			VoucherVo vo = new VoucherVo();
			vo.setCertNo(c_deposit.getCertNo());
			vo.setBusinessTypeName("开通自行车应用,押金和首充业务");
			vo.setCardType(cardType.getCardTypeName());
			vo.setOperator(activeUser.getUserNo().toString());
			vo.setNet(activeUser.getBranchNo());
			vo.setAriginalAmount(CommonUtil.convertMoney_00(money));
			// 20181206 hgl 修改以下两行
			vo.setTransactionAmount(balance);
			vo.setFeeBln(feeRules.getFeeBln().toString());
			vo.setCurrentAmount("0.00");
			vo.setTransactionDate(DateFormatUtils.format(now, "yyyy-MM-dd HH:mm:ss"));
			vo.setDate(DateFormatUtils.format(now, "yyyy-MM-dd"));
			return vo;
		} else {
			// 此卡异常，不得开通应用，请先查询卡状态
			throw new ApplicationException(ErrorCode.CARD_STATUS_EXCEPTION, "卡片状态异常，无法关闭应用");
		}

	}

	@Test
	public void test() {
		// 请求地址 root PathContants.BIKE_SERVICE_API
		String url = "http://61.160.81.178:18006/qzbike/api/bike/queryBikeUserByIDNumber";
		List<NameValuePair> parameForToken = new ArrayList<NameValuePair>();
		parameForToken.add(new BasicNameValuePair("mode", "03"));
		parameForToken.add(new BasicNameValuePair("idtype", "00"));
		parameForToken.add(new BasicNameValuePair("idno", "320721199108155211"));
		JSONObject jo = HttpUtil.doPost(url, parameForToken);
		System.out.println(jo.getString("head"));
		ResponseHead g = JSON.parseObject(jo.getString("head"), ResponseHead.class);

		System.out.println(g.toString());
		System.out.println("hah" + jo.getJSONObject("head").getString("rsltdesc"));

	}

	// -----------------交易代码-------------
	/**
	 * 请求通过
	 */
	private static String code0000 = "0000";

	/**
	 * 表示查无相关信息
	 */
	private static String code0001 = "0001";

	/**
	 * 证件号码不合法或年龄越界
	 */
	private static String code0002 = "0002";

	/**
	 * 证件已开通租车功能
	 */
	private static String code0003 = "0003";
	/**
	 * 卡片已开通租车功能
	 */
	private static String code0004 = "0004";

	/**
	 * 原会员号不存在或者原会员号已经注销不允许进行业务操作
	 */
	private static String code0005 = "0005";

	/**
	 * 旧卡片不允许直接换卡或重写
	 */
	private static String code0006 = "0006";

	/**
	 * 新卡已经被使用不能换卡
	 */
	private static String code0007 = "0007";

	/**
	 * 新旧会员信息相同不是换新卡
	 */
	private static String code0008 = "0008";
	/**
	 * 重写卡时传入的信息和系统中存在的信息不一致
	 */
	private static String code0009 = "0009";
	/**
	 * 会员卡状态与操作目的一致无须更新
	 */
	private static String code0010 = "0010";
	/**
	 * 
	 */
	private static String code0011 = "0011";
	/**
	 * 退卡失败，并在响应信息中返回退卡失败的原因
	 */
	private static String code0012 = "0012";
	/**
	 * 请求不通过或其他异常
	 */
	private static String code9999 = "9999";

	// -----------------借还状态-------------
	/**
	 * 禁止借车
	 */
	private static String allowStatus_no = "01";

	/**
	 * 允许借车
	 */
	private static String allowStatus_yes = "00";

	// -----------------查询条件类型-------------

	private static String paramType_01 = "01";

	private static String paramType_02 = "02";

	private static String paramType_03 = "03";

	// -----------------卡片物理类型-------------
	private static String cardtype = "03";

	// -----------------挂失/解挂状态-------------
	/**
	 * 挂失
	 */
	private static String loss_status = "01";

	/**
	 * 解挂
	 */
	private static String unbind_status = "00";

	// -----------------查询消费记录条件-------------

	/**
	 * 查询用车记录(包含产生费用的记录)
	 */
	private static String reqtype_all = "00";

	/**
	 * 查询产生消费的记录
	 */
	private static String reqtype_consumeRecord = "01";

	// -----------------交易记录是否结束-------------
	/**
	 * 00表示记录没有传输完毕，客户端收到反馈后可以使用本包最大sn+1进行请求；
	 */
	private static String finish_no = "00";

	/**
	 * 01表示记录传输完毕。
	 */
	private static String finish_yes = "01";

	@Override
	public JSONObject queryBikeUserByCitizenCardNo(String citizenCardNo) throws ApplicationException {
		// 查询是否已办理自行车卡
		List<NameValuePair> parameForToken = new ArrayList<NameValuePair>();
		parameForToken.add(new BasicNameValuePair("mode", "01"));
		parameForToken.add(new BasicNameValuePair("cardfaceno", citizenCardNo));
		return doPostBike(parameForToken, PreServcieContants.bikeServiceIp + PreServcieContants.queryBikeUserByIDNumber);
	}

	@Override
	public JSONObject queryBikeUserByVipNo(String vipno) throws ApplicationException {
		// 查询是否已办理自行车卡
		List<NameValuePair> parameForToken = new ArrayList<NameValuePair>();
		parameForToken.add(new BasicNameValuePair("mode", "02"));
		parameForToken.add(new BasicNameValuePair("vipno", vipno));
		return doPostBike(parameForToken, PreServcieContants.bikeServiceIp + PreServcieContants.queryBikeUserByIDNumber);
	}

	@Override
	public JSONObject queryBikeUserByIdNo(String idtype, String idNo) throws ApplicationException {
		// 查询是否已办理自行车卡
		List<NameValuePair> parameForToken = new ArrayList<NameValuePair>();
		parameForToken.add(new BasicNameValuePair("mode", "03"));
		parameForToken.add(new BasicNameValuePair("idtype", idtype));
		parameForToken.add(new BasicNameValuePair("idno", idNo));
		return doPostBike(parameForToken, PreServcieContants.bikeServiceIp + PreServcieContants.queryBikeUserByIDNumber);
	}

	@Override
	public JSONObject doPostBike(List<NameValuePair> parameForToken, String url) throws ApplicationException {
		JSONObject js = HttpUtil.doPost(url, parameForToken);
		ResponseHead g = JSON.parseObject(js.getString("head"), ResponseHead.class);
		if (code9999.equals(g.getRsltcode())) {
			throw new ApplicationException(ErrorCode.OTHER_EXCEPTION, g.getRsltdesc());
		}
		return js;
	}

	@Override
	public JSONObject writeData(String cardsn, String cardtype, String cardfaceno, String idtype, String idno,
			String birthday) throws ApplicationException {
		List<NameValuePair> parameForToken = new ArrayList<NameValuePair>();
		parameForToken.add(new BasicNameValuePair("cardsn", cardsn));
		parameForToken.add(new BasicNameValuePair("cardtype", cardtype));
		parameForToken.add(new BasicNameValuePair("cardfaceno", cardfaceno));
		parameForToken.add(new BasicNameValuePair("idtype", idtype));
		parameForToken.add(new BasicNameValuePair("idno", idno));
		parameForToken.add(new BasicNameValuePair("birthday", birthday));
		JSONObject js = HttpUtil.doPost(PreServcieContants.bikeServiceIp + PreServcieContants.writeCardData,
				parameForToken);
		ResponseHead g = JSON.parseObject(js.getString("head"), ResponseHead.class);
		if (!code0000.equals(g.getRsltcode())) {
			throw new ApplicationException(ErrorCode.OTHER_EXCEPTION, g.getRsltdesc());
		}
		return js;
	}

	@Override
	public JSONObject regMemberInfo(String cardsn, String citizenCardNo, String vipno, String vipcardsn,
			String vipname, String sex, String idtype, String idno, String birthday, String recharge,
			BigDecimal deposit, String address, String mobilephone, String linkman, String linkphone)
			throws ApplicationException {
		List<NameValuePair> parameForToken = new ArrayList<NameValuePair>();
		parameForToken.add(new BasicNameValuePair("cardsn", cardsn));
		parameForToken.add(new BasicNameValuePair("cardfaceno", citizenCardNo));
		parameForToken.add(new BasicNameValuePair("vipno", vipno));
		parameForToken.add(new BasicNameValuePair("vipcardsn", vipcardsn));
		parameForToken.add(new BasicNameValuePair("vipname", vipname));
		parameForToken.add(new BasicNameValuePair("sex", sex));
		parameForToken.add(new BasicNameValuePair("idtype", idtype));
		parameForToken.add(new BasicNameValuePair("idno", idno));
		parameForToken.add(new BasicNameValuePair("birthday", birthday));
		parameForToken.add(new BasicNameValuePair("recharge", CommonUtil.convertMoney(new BigDecimal(recharge))));
		parameForToken.add(new BasicNameValuePair("deposit", CommonUtil.convertMoney(deposit)));
		parameForToken.add(new BasicNameValuePair("address", address));
		parameForToken.add(new BasicNameValuePair("mobilephone", mobilephone));
		parameForToken.add(new BasicNameValuePair("linkman", linkman));
		parameForToken.add(new BasicNameValuePair("linkphone", linkphone));

		JSONObject js = HttpUtil.doPost(PreServcieContants.bikeServiceIp + PreServcieContants.regMemberInfo,
				parameForToken);
		ResponseHead g = JSON.parseObject(js.getString("head"), ResponseHead.class);

		if (!code0000.equals(g.getRsltcode())) {
			throw new ApplicationException(ErrorCode.OTHER_EXCEPTION, g.getRsltdesc());
		}

		return js;

	}

	@Override
	public JSONObject memberBorrowOrBackLastTime(String vipno, String vipcardsn) throws ApplicationException {
		// 请求最后一次借还状态
		List<NameValuePair> parameForToken = new ArrayList<NameValuePair>();
		parameForToken.add(new BasicNameValuePair("vipno", vipno));
		parameForToken.add(new BasicNameValuePair("vipcardsn", vipcardsn));

		return doPostBike(parameForToken, PreServcieContants.bikeServiceIp
				+ PreServcieContants.memberBorrowOrBackLastTime);
	}

	@Override
	public JSONObject memberExchangeNewCard(String oldvipno, String newCardsn, String newCitizenCardNo)
			throws ApplicationException {
		List<NameValuePair> parameForToken = new ArrayList<NameValuePair>();
		parameForToken.add(new BasicNameValuePair("oldvipno", oldvipno));
		parameForToken.add(new BasicNameValuePair("cardsn", newCardsn));
		parameForToken.add(new BasicNameValuePair("cardfaceno", newCitizenCardNo));

		return doPostBike(parameForToken, PreServcieContants.bikeServiceIp + PreServcieContants.memberExchangeNewCard);

	}

	@Override
	public JSONObject successExchangeNewCard(String newCardsn, String newCitizenCardNo, String oldVipno,
			String oldVipcardsn, String newVipno, String newVipcardsn) throws ApplicationException {
		List<NameValuePair> parameForToken = new ArrayList<NameValuePair>();
		parameForToken.add(new BasicNameValuePair("cardsn", newCardsn));
		parameForToken.add(new BasicNameValuePair("cardfaceno", newCitizenCardNo));
		parameForToken.add(new BasicNameValuePair("oldvipno", oldVipno));
		parameForToken.add(new BasicNameValuePair("oldvipcardsn", oldVipcardsn));
		parameForToken.add(new BasicNameValuePair("newvipno", newVipno));
		parameForToken.add(new BasicNameValuePair("newvipcardsn", newVipcardsn));

		return doPostBike(parameForToken, PreServcieContants.bikeServiceIp + PreServcieContants.successExchangeNewCard);
	}

	@Override
	public VoucherVo bikeAppRecharge(String citizenCardNo, String recharge, String vipno, String vipcardsn,
			String balance) throws ApplicationException {
		ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getSession().getAttribute("activeUser");

		CardControl query_CardControl = cardControlMapper.queryCardControlByCitizenCardNo(citizenCardNo);

		if (query_CardControl == null) {
			throw new ApplicationException(ErrorCode.QUERY_DATA_NULL, "当前卡片查询不到信息");
		}
		if (query_CardControl.getCardStatus().equals(CardContants.CARD_STATE_NORMAL)) {

			AppOpenReg query_AppOpenReg = appOpenRegMapper.checkIsOpen(citizenCardNo, AppContants.APP_FLAG_BIKE);
			if (query_AppOpenReg == null) {
				throw new ApplicationException(ErrorCode.QUERY_DATA_NULL, "当前卡片没有开通自行车应用");
			}

			Personal query_Personal = personalMapper.queryPersonalBycitizenCardNo(citizenCardNo);
			if (query_Personal == null) {
				throw new ApplicationException(ErrorCode.QUERY_DATA_NULL, "当前卡片无个人信息");
			}

			Business business = new Business();
			business.setBusinessNo(SequenceNumberUtil.generatorBusinessNo());
			// 请求充值
			JSONObject js = memberCardRecharge(vipno, vipcardsn, recharge, business.getBusinessNo());
			ResponseHead g = JSON.parseObject(js.getString("head"), ResponseHead.class);
			if (!code0000.equals(g.getRsltcode())) {
				throw new ApplicationException(ErrorCode.OTHER_EXCEPTION, g.getRsltdesc());
			}

			CardData cardData = cardDataMapper.queryCardDataByCitizenCardNo(citizenCardNo);

			// 充值凭证
			Date now = new Date();
			Cert cert = new Cert();
			cert.setCertNo(SequenceNumberUtil.generatorCertNo());
			cert.setCardControlId(query_CardControl.getCardControlId());
			cert.setCertType(CardContants.BIKE_RECHARGE_VOUCHER);
			cert.setCardpCode(cardData.getCardpCode());
			cert.setCardTypecode(cardData.getCardTypecode());
			cert.setName(query_Personal.getCustomerName());
			cert.setPaperType(query_Personal.getPaperType());
			cert.setPaperNo(query_Personal.getPaperNo());
			// c.setStatus(status);
			cert.setData("充值本金凭证");
			cert.setBusinessNo(business.getBusinessNo());
			cert.setBranchNo(activeUser.getBranchNo());
			cert.setCrtOperator(activeUser.getUserNo().toString());
			cert.setCrtDate(now);
			cert.setLastOperator(activeUser.getUserNo().toString());
			cert.setLastDate(now);
			cert.setBranch(activeUser.getBranchName());

			business.setCardControlId(query_CardControl.getCardControlId());
			business.setCustomerNo(query_Personal.getCustomerNo());
			business.setCardpCode(cardData.getCardpCode());
			business.setTellerNo(activeUser.getUserNo().toString());
			business.setTransDate(now);
			business.setSeqStatus(CardContants.LSZT_NORMAL);
			business.setCertNo(cert.getCertNo());

			// 自行车充值记录
			// 当日交易明细
			TxnDtl txnDtl = new TxnDtl();
			txnDtl.setCitizenCardNo(citizenCardNo);
			txnDtl.setIssCityCd(CardContants.CITY_CODE);
			txnDtl.setTxnCityCd(CardContants.CITY_CODE);
			txnDtl.setAppFlag(AppContants.APP_FLAG_BIKE);
			txnDtl.setCrdPhysTp(cardData.getCardPhysicalType());// 卡物理类型
			txnDtl.setCashFlag(AccountContants.CASH_FLAG_COLLECT); // 现金收付标志
																	// 0.无,1.收取
																	// 2.支出,3.收支
			// txnDtl. setTxnTp(bv.getCrdTxnType());// 卡交易类型 02 06
			txnDtl.setTxnDt(DateFormatUtils.format(now, "yyyyMMddHHmmss"));
			txnDtl.setTxnBalBef(CommonUtil.convertMoney_1(balance));// 账户交易前余额
			BigDecimal money = new BigDecimal(recharge);
			BigDecimal total = money.add(CommonUtil.convertMoney_1(balance));
			txnDtl.setTxnBalAft(total);
			txnDtl.setTxnAmt(money);
			txnDtl.setFeeTp(AccountContants.FEE_TYPE_PRINCIPAL);// 费用类型 0.本金
																// 1:工本费 2.交易手续费
																// 3:租金4:押金
			txnDtl.setAcceptTp(AccountContants.ACCEPTANCE_TYPE_NET);
			txnDtl.setAcceptCusNo(activeUser.getBranchNo());// 受理商户/网点编号
			txnDtl.setTxnTstFlg(AccountContants.TRANSACTION_TEST_FLAG_COMMON);// 交易测试标志
																				// "0"-普通;
																				// "1"-测试
			txnDtl.setTxnAdjFlg(AccountContants.TRANSACTION_FLOW_FLAG_NORMAL);// 交易流水标志
																				// "00"
																				// 正常
																				// "41"
																				// 撤销
			txnDtl.setWarrantid(cert.getCertNo());// 凭证号
			txnDtl.setOprNo(activeUser.getUserNo().toString());// 操作员编号/终端操作员编号
			txnDtl.setTxnAttr(AccountContants.TXNTP_RECHARGE);// 交易性质
			txnDtl.setCrdCityCd(CardContants.CITY_CODE);// 卡城市代码
			txnDtl.setCardType(cardData.getCardTypecode());
			txnDtl.setRsvdFlags(AccountContants.TXNTP_RECHARGE); // 预留标志组
			txnDtl.setTxnType(AccountContants.TRADE_TYPE_BIKE);// 终端交易类型
			txnDtl.setTxnDate(DateFormatUtils.format(now, "yyyyMMdd")); // 交易日期
			txnDtl.setBusinessNo(txnDtl.getBusinessNo());//
			txnDtl.setPaymentType(AccountContants.PAYMENT_TYPE_CASH);// 支付方式 0
																		// 现金 1
																		// 兑换券
																		// 默认为0
			txnDtl.setPaymentTypeExt(AccountContants.STATUS_INVALID);// 支付方式是否扩展
																		// 0 否1
																		// 是
																		// 默认为0
			txnDtl.setRealTxnAmt(total);

			// 交易明细流水表
			TransGlide transGlide = new TransGlide();
			transGlide.setAcceptTp(AccountContants.ACCEPTANCE_TYPE_NET);// 受理类型
			transGlide.setAppFlag(AppContants.APP_FLAG_BIKE);// 应用标识
			transGlide.setAppType(query_AppOpenReg.getAppType());// 应用类型
			transGlide.setBranchNo(activeUser.getBranchNo());
			transGlide.setCitizenCardNo(citizenCardNo);// 市民卡号
			transGlide.setCashFlag(AccountContants.CASH_FLAG_COLLECT);// 现金收付标志
			// transGlide.setFeeRuleId(feeRules.getFeeRuleId());//卡费用规则ID
			// transGlide.setFeeRulesId(feeRules.getFeeRulesId());//卡费用细则ID
			transGlide.setFeeTp(AccountContants.FEE_TYPE_PRINCIPAL);// 费用类型
			transGlide.setOprNo(activeUser.getUserNo().toString());
			transGlide.setPaymentType(AccountContants.PAYMENT_TYPE_CASH);// 现金
			transGlide.setPaymentTypeExt(AccountContants.STATUS_INVALID);
			transGlide.setRptFlag(AccountContants.RPT_FLAG_NO);// 轧帐标识 0未过账
			transGlide.setTxnAdjFlg(AccountContants.TRANSACTION_FLOW_FLAG_NORMAL);// 交易流水标识
			transGlide.setTxnAmt(money);// 交易金额
			transGlide.setTxnDt(now);// 交易时间
			transGlide.setTxnTp(AccountContants.TXNTP_RECHARGE);// txnTp 交易类型
			transGlide.setBusinessNo(txnDtl.getBusinessNo());
			certMapper.insert(cert);
			businessMapper.insert(business);
			txnDtlMapper.insert(txnDtl);
			transGlideMapper.insert(transGlide);

			CardType cardType = cardTypeMapper.queryCardTypeByCode(cardData.getCardTypecode());

			VoucherVo vo = new VoucherVo();
			vo.setCertNo(cert.getCertNo());
			vo.setBusinessTypeName("自行车充值业务");
			vo.setCardType(cardType.getCardTypeName());
			vo.setOperator(activeUser.getUserNo().toString());
			vo.setNet(activeUser.getBranchNo());
			vo.setTransactionAmount(CommonUtil.convertMoney_00(money));
			vo.setCurrentAmount(CommonUtil.convertMoney_00(total));
			vo.setTransactionDate(DateFormatUtils.format(now, "yyyy-MM-dd HH:mm:ss"));
			vo.setDate(DateFormatUtils.format(now, "yyyy-MM-dd"));

			return vo;
		} else {
			// 此卡异常，请先查询卡状态
			throw new ApplicationException(ErrorCode.CARD_STATUS_EXCEPTION, "卡片状态异常，无法充值");
		}

	}

	@Override
	public JSONObject memberCardRecharge(String vipno, String vipcardsn, String recharge, String tradenumber)
			throws ApplicationException {
		List<NameValuePair> parameForToken = new ArrayList<NameValuePair>();
		parameForToken.add(new BasicNameValuePair("vipno", vipno));
		parameForToken.add(new BasicNameValuePair("vipcardsn", vipcardsn));
		parameForToken.add(new BasicNameValuePair("recharge", recharge));

		return doPostBike(parameForToken, PreServcieContants.bikeServiceIp + PreServcieContants.memberCardRecharge);

	}

	@Override
	public JSONObject rechargeReverse(String vipno, String vipcardsn, String tradenumber) throws ApplicationException {

		List<NameValuePair> parameForToken = new ArrayList<NameValuePair>();
		parameForToken.add(new BasicNameValuePair("vipno", vipno));
		parameForToken.add(new BasicNameValuePair("vipcardsn", vipcardsn));
		parameForToken.add(new BasicNameValuePair("tradenumber", tradenumber));

		return doPostBike(parameForToken, PreServcieContants.bikeServiceIp + PreServcieContants.rechargeReverse);

	}

	@Override
	public JSONObject updateMemberInfo(String vipno, String vipcardsn, String vipname, String sex, String idtype,
			String idno, String birthday, String address, String mobilephone, String linkman, String linkphone)
			throws ApplicationException {
		List<NameValuePair> parameForToken = new ArrayList<NameValuePair>();
		parameForToken.add(new BasicNameValuePair("vipno", vipno));
		parameForToken.add(new BasicNameValuePair("vipcardsn", vipcardsn));
		parameForToken.add(new BasicNameValuePair("vipname", vipname));
		parameForToken.add(new BasicNameValuePair("sex", sex));
		parameForToken.add(new BasicNameValuePair("idtype", idtype));
		parameForToken.add(new BasicNameValuePair("idno", idno));

		parameForToken.add(new BasicNameValuePair("birthday", birthday));
		parameForToken.add(new BasicNameValuePair("address", address));
		parameForToken.add(new BasicNameValuePair("mobilephone", mobilephone));
		parameForToken.add(new BasicNameValuePair("linkman", linkman));
		parameForToken.add(new BasicNameValuePair("linkphone", linkphone));
		return doPostBike(parameForToken, PreServcieContants.bikeServiceIp + PreServcieContants.updateMemberInfo);

	}

	@Override
	public JSONObject cardReportLossOrRelease(String vipno, String newstate) throws ApplicationException {
		List<NameValuePair> parameForToken = new ArrayList<NameValuePair>();
		parameForToken.add(new BasicNameValuePair("vipno", vipno));
		parameForToken.add(new BasicNameValuePair("newstate", newstate));

		return doPostBike(parameForToken, PreServcieContants.bikeServiceIp + PreServcieContants.cardReportLossOrRelease);

	}

	@Override
	public JSONObject rewriteMemberCardData(String cardsn, String citizenCardNo, String vipno, String vipcardsn)
			throws ApplicationException {
		List<NameValuePair> parameForToken = new ArrayList<NameValuePair>();
		parameForToken.add(new BasicNameValuePair("cardsn", cardsn));
		parameForToken.add(new BasicNameValuePair("cardfaceno", citizenCardNo));
		parameForToken.add(new BasicNameValuePair("vipno", vipno));
		parameForToken.add(new BasicNameValuePair("vipcardsn", vipcardsn));

		return doPostBike(parameForToken, PreServcieContants.bikeServiceIp + PreServcieContants.rewriteMemberCardData);

	}

	@Override
	public JSONObject backCard(String vipno) throws ApplicationException {
		List<NameValuePair> parameForToken = new ArrayList<NameValuePair>();
		parameForToken.add(new BasicNameValuePair("vipno", vipno));
		return doPostBike(parameForToken, PreServcieContants.bikeServiceIp + PreServcieContants.backCard);
	}

	@Test
	public void testJson() {
		String jsonString = "{\"head\":{\"rsltcode\":\"0000\",\"rsltdesc\":\"\",\"tradecode\":\"0002\",\"tradetime\":\"20180927180239\",\"tradenumber\":\"000599565\",\"src\":\"00\",\"dest\":\"A0\"},\"body\":{\"cardsn\":\"90ac450c\",\"sectioninfo\":[{\"no\":\"01\",\"keya\":\"aac6435b7e65\",\"keyb\":\"241fda2448e0\",\"contrlword\":\"FF078069\"},{\"no\":\"02\",\"keya\":\"a9c540587d66\",\"keyb\":\"271cd9274be3\",\"contrlword\":\"FF078069\"}]}}";
		JSONObject js = JSON.parseObject(jsonString);

		List<BikeSection> list = JSONArray.parseArray(js.getJSONObject("body").getJSONArray("sectioninfo")
				.toJSONString(), BikeSection.class);
		for (BikeSection b : list) {
			System.out.println(b.toString());
		}
	}

	@Override
	public List<BikeConsumeRecord> consumeRecord(String vipno, String vipcardsn, String startdate, String enddate,
			String reqtype, String sn, List<BikeConsumeRecord> list) throws ApplicationException {
		List<NameValuePair> parameForToken = new ArrayList<NameValuePair>();
		parameForToken.add(new BasicNameValuePair("vipno", vipno));
		parameForToken.add(new BasicNameValuePair("vipcardsn", vipcardsn));
		parameForToken.add(new BasicNameValuePair("startdate", startdate));
		parameForToken.add(new BasicNameValuePair("enddate", enddate));
		parameForToken.add(new BasicNameValuePair("reqtype", reqtype));
		parameForToken.add(new BasicNameValuePair("sn", sn));

		JSONObject js = doPostBike(parameForToken, PreServcieContants.bikeServiceIp + PreServcieContants.consumeRecord);
		js = js.getJSONObject("body");
		String finish = js.getString("finish");
		JSONArray ja = js.getJSONArray("record");
		List<BikeConsumeRecord> list_q = JSONArray.parseArray(ja.toJSONString(), BikeConsumeRecord.class);
		if(list_q.size() == 0){
			throw new ApplicationException(ErrorCode.OTHER_EXCEPTION, "自行车暂无交易记录");

		}
		list.addAll(list_q);

		if (finish_no.equals(finish)) {// 记录未传输完成
			sn = list.get(list.size()).getSn();
			consumeRecord(vipno, vipcardsn, startdate, enddate, reqtype, sn + 1, list);

		}

		return list;
	}

	@Override
	public List<BikeConsumeRecord> bikeAppqueryConsumeRecord(String citizenCardNo, String startdate, String enddate)
			throws ApplicationException {
		JSONObject js = queryBikeUserByCitizenCardNo(citizenCardNo);
		ResponseHead g = JSON.parseObject(js.getString("head"), ResponseHead.class);
		if (code0001.equals(g.getRsltcode())) {
			throw new ApplicationException(ErrorCode.OTHER_EXCEPTION, "当前卡片未开通自行车应用");
		}
		js = js.getJSONObject("body");
		String vipno = js.getString("vipno");
		String vipcardsn = js.getString("vipcardsn");

		List<BikeConsumeRecord> list = new ArrayList<>();

		return query(startdate, enddate, list, vipno, vipcardsn);
	}

	public List<BikeConsumeRecord> query(String startdate, String enddate,List<BikeConsumeRecord> list,String vipno,String vipcardsn) throws ApplicationException {
		Date start;
		Date end;
		try {
			start = DateUtils.parseDate(startdate, "YYYYMMDD");
			end = DateUtils.parseDate(enddate, "YYYYMMDD");
		} catch (ParseException e) {
			e.printStackTrace();
			throw new ApplicationException(SystemException.ParseException, "查询交易记录日期转换失败");
		}

		list = consumeRecord(vipno, vipcardsn, startdate, enddate, reqtype_consumeRecord, "1", list);

		                              
		if (CommonUtil.differentDays(start, end) > 31) {
			   Calendar calendar_start=Calendar.getInstance();   
			   calendar_start.setTime(start); 
			   calendar_start.set(Calendar.DAY_OF_MONTH,calendar_start.get(Calendar.DAY_OF_MONTH)+30);//让日期加30 
			
			   
			   List<BikeConsumeRecord> list_q = query(DateFormatUtils.format(calendar_start, "YYYYMMDD"), enddate, list, vipno, vipcardsn);
			   if(list_q.size()>0)
			   list.addAll(list_q);
			
		}
		
		
		
		return list;
		
	}

}
